// ==UserScript==        
// @name           Help Forum Tweaks
// @namespace      http://www/~johnmu/greasemonkey/help-forum-tweaks.user.js
// @description    Tweaks for the Google Help Forums
// @version        0.40
// @include        http://www.google.com/support/forum/p/*
// ==/UserScript==

/*
Copyright 2009 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/* Requires Chrome 2.x with user-scripts enabled
** or Mozilla FireFox with Greasemonkey Extensions.
**
** See http://dev.chromium.org/developers/design-documents/user-scripts
** or http://lifehacker.com/5180010/enable-user-scripts-in-google-chrome
**
** Make sure to put it in the right location, eg:
** C:\Documents and Settings\yourname\Local Settings\Application Data\
**     Google\Chrome\User Data\Default\User Scripts
** and restart Chrome with the option " --enable-user-scripts"
**
** Last Update: 25 September 2009
*/

var URL = window.location.href; 
String.prototype.startsWith = function(s) { return this.indexOf(s)==0; }

// Google Chrome Support Code
if( !GM_getValue && !GM_setValue && !unsafeWindow ) {
  function GM_setValue( cookieName, cookieValue, lifeTime ) {
    if( !cookieName ) { return; }
    if( lifeTime == "delete" ) { lifeTime = -10; }
                          else { lifeTime = 31536000; }
    document.cookie = escape( cookieName ) + "=" + escape( cookieValue ) +
      ";expires=" + ( new Date( ( new Date() ).getTime() + 
      ( 1000 * lifeTime ) ) ).toGMTString() + ";path=/";
  }

  function GM_getValue( cookieName, oDefault ) {
    var cookieJar = document.cookie.split( "; " );
    for( var x = 0; x < cookieJar.length; x++ ) {
      var oneCookie = cookieJar[x].split( "=" );
      if( oneCookie[0] == escape( cookieName ) ) {
        try {
          var footm = unescape(oneCookie[1]);
        } catch(e) { return oDefault; }
        return footm;
      }
    }
    return oDefault;
  }

  function GM_registerMenuCommand( oText, oFunc ) {}

  window.unsafeWindow = window;
}

// Show the links in the sidebar
function showSideLinks(serialized_data) {
  var entries = serialized_data.split("\t");
  var side_ul = document.getElementById("wparoot");
  if (side_ul) {
    for (i=0; i<entries.length; i++) {
      var suburl = entries[i].match(/\"(.*?)\"/);
      var subtitle = entries[i].match(/>(.*?)</);
      var subclass = entries[i].match(/class="(.*?)"/);
      if (!subclass) {
        var new_li = document.createElement("li");
        new_li.id = "new_li_" + i;
        new_li.className = "wpabaruhCSS";
        var new_a = document.createElement("a");
        new_a.href = suburl[1];
        new_a.innerHTML = subtitle[1];
        new_li.appendChild(new_a);
        side_ul.appendChild(new_li);
      }
    }
    var languageCode = URL.match("[\?&]hl=([^&#]*)")[1];
    var forumName = URL.match("/forum\/p\/([^/]*)[/\?]")[1];
    var new_li = document.createElement("li");
    new_li.id = "new_li_" + (i+1);
    new_li.className = "wpabaruhCSS";
    var new_a = document.createElement("a");
    new_a.href = "http://www.google.com/support/forum/p/" + 
        forumName + "/browse?hl=" + languageCode;
    new_a.innerHTML = "Alle Threads";
    new_li.appendChild(new_a);
    side_ul.appendChild(new_li);
  }
}

// fix editor window: make larger, fix horizontal scrolling
function fixEditorTextField() {
  // Editor is made up of multiple frames, we must fix two of them
  try {
    if (document.getElementById("wmfroot")) {
      // on thread page, change size of editor div to double height
      var newCSS = "div#wpiprde.wpiprdeCSS { height: 300px !important; }";
      GM_addStyle(newCSS);
      // for non-richtext editor users, adjust row count in text area
      var newCSS = "textarea#wpiprdi { height: 300px !important; }";
      GM_addStyle(newCSS);
    } else if (document.body.id=="wpiprde") {
      // in the editor page (iframed), update CSS for fixed word wrap
      var newCSS = 'body#wpiprde.editable { width: 100% !important; }';
      GM_addStyle(newCSS);
    }
  } catch (ex) { }
}

// Add bottom anchor to page
function jumpToBottom() {
  try {
    var hash = document.location.hash.toString();
    if (hash=="#all") {
      var answerNode = document.getElementById("wpsfm"); // info bar
      if (!answerNode) answerNode = document.getElementById("wpcprie");
      var newNode = document.createElement("a");
      newNode.name = "bottomPage";
      answerNode.parentNode.insertBefore(newNode, answerNode);
      var gotoY = newNode.offsetTop;
      window.scrollTo(0, gotoY-(window.innerHeight-200));
    }
  } catch(ex) { } 
}

// adds a link to the last post in the forum overview page
function addLinkToLastPost() {
  try {
    if (document.getElementById("wlhd")) {
      // traverse table, extract link to post, add to last answer date
      var rows = document.getElementsByTagName("tr");
      for (var i=0; i<rows.length;i++) {
        var row = rows[i];
        var tds = row.getElementsByTagName("td");
        if (tds.length==5 || tds.length==6) {
          // get thread URL
          var temp= row.innerHTML.match(
              "\/support\/forum\/p\/[a-zA-Z0-9 ]*?\/thread.*?\"");
          if (temp) {
            var threadUrl = temp[0].substring(
                0, temp[0].length-1).replace("&amp;","&");
            var lastPost = tds[tds.length-1];
            // this wraps the link around the whole contents, which may
            // also include a <div> element, which may look weird in
            // Firefox but it works :-)
            lastPost.innerHTML = "<a href=\"" + threadUrl + "#all\">" + 
                lastPost.innerHTML + "</a>";
          }
        }
      } 
    }
  } catch (ex) { }
}


// hack for Chrome implementation of @include
if (URL.startsWith("http://www.google.com/support/forum/p/")) {
  // ---------------------------------------------
  // Feel free to change these colors and settings
  // Remember to restart Chrome when making changes.
  // ---------------------------------------------
  var color_read_by_you    = "#EFEFEF";
  var color_read_by_others = "#FFFFFF" ; "#E7EFFF";
  var title_font_size      = "15px"; 
  var thread_title_bold    = true; // "true" or "false"
  var show_side_links      = true; // "true" or "false"
  var resize_editor        = true; // "true" or "false"
  var link_to_last         = true; // "true" or "false"

  // ---------------------------------------------
  // You probably don't have to change anything below here
  // ---------------------------------------------

  // inject the CSS styles  
  if (thread_title_bold) GM_addStyle(
      'td.lcnCSS div:first-child a { font-weight:bold; }');
  if (thread_title_bold) GM_addStyle(
      'td.wltbsCSS div:first-child a { font-weight:normal; }');
  if (thread_title_bold) GM_addStyle(
      'td.wltbgCSS div:first-child a { font-weight:normal; }');
  GM_addStyle('table.lctCSS td div:first-child a { font-size: ' + 
      title_font_size + '; }');
  GM_addStyle('td.wltbsCSS { background-color: ' + 
      color_read_by_you + '; }');
  GM_addStyle('td.wltbsCSS div { background-color: ' + 
      color_read_by_you + '; }');
  GM_addStyle('td.wltbtcCSS { background-color: ' + 
      color_read_by_others + '; }');
  GM_addStyle('td.wltbtcCSS div { background-color: ' + 
      color_read_by_others + '; }');

  if (resize_editor) fixEditorTextField();
  jumpToBottom();
  
  if (link_to_last) addLinkToLastPost();
  
  if (show_side_links) {
    // inject the subforum links
    var languageCode = URL.match("[\?&]hl=([^&#]*)")[1];
    var forumName = URL.match("/forum\/p\/([^/]*)[/\?]")[1];
    var forumKey = forumName + "_" + languageCode;

    var cachedEntries = "";
    var cachedDate = GM_getValue(forumKey + "_cached", "");
    var currentDate = new Date();
    
    if (cachedDate!="") {
      // check if cache is still valid (24 hrs)
      if (currentDate - Date.parse(cachedDate)<(86400 * 1000)) {
        cachedEntries = GM_getValue(forumKey, "");
      }
    }
    if (cachedEntries != "") { 
      showSideLinks(cachedEntries);
    } else {
      // fetch sub-forum links from the forum homepage
      var theurl = "http://www.google.com/" + 
          "support/forum/p/" + forumName + "?hl=" + languageCode;
      var request = new XMLHttpRequest();
      request.onreadystatechange = function() {
        if ((request.readyState == 4) && (request.status == 200)) {
          var doc = request.responseText;
          var entries = doc.match(/href=.*?lid=.*?</g);
          var serialized = entries.join("\t");
          GM_setValue(forumKey, serialized); // cache data
          GM_setValue(forumKey + "_cached", currentDate.toString());
          showSideLinks(serialized);
        }
      }
      request.open('GET', theurl, true);
      request.send(null);
    }
  }
}

